﻿using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc.Validation;
using Volo.Abp.Modularity;

namespace Gateway.UI.Api.AbpModules
{
    /// <summary>
    /// 
    /// </summary>
    [DependsOn()]
    public class KestrelModule : AbpModule
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override Task ConfigureServicesAsync(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
            //这里是关闭自动验证的--模型验证  然后 就能到 自己的 模型验证里去
            context.Services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });

            context.Services.AddMyAuthentication(configuration);

            #region 跨域

            context.Services.AddCors(options => options.AddPolicy("AllowCors",
                builders =>
                {
                    builders.AllowAnyMethod()
                        .AllowAnyHeader()
                        .SetIsOriginAllowed(_ => true) // =AllowAnyOrigin()
                        .AllowCredentials();
                }));

            #endregion


            context.Services.AddControllers(options =>
            {
                options.Filters.Add<GlobalExceptionFilter>();
                options.Filters.Add<ModelValidateActionFilterAttribute>();
                options.Filters.Add<ResultFilter>();
                options.Filters.Add<AuthorizationFilter>();
                options.Filters.Add<LogFilter>();
                options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
                
                var filterMetadata = options.Filters.FirstOrDefault(x =>
                    x is ServiceFilterAttribute attribute && attribute.ServiceType == typeof(AbpExceptionFilter));
                if (filterMetadata != null)
                    options.Filters.Remove(filterMetadata);
                
                var validateFilterMetadata = options.Filters.FirstOrDefault(x =>
                    x is ServiceFilterAttribute attribute && attribute.ServiceType == typeof(AbpValidationActionFilter));
                if (validateFilterMetadata != null)
                    options.Filters.Remove(validateFilterMetadata);
                
                
            }).AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver =
                    new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); //json字符串大小写原样输出
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            });

            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            context.Services.AddEndpointsApiExplorer();


            context.Services.AddRouting(options => { options.LowercaseUrls = true; });


            context.Services.AddCoreSwagger();


            context.Services.AddHttpContextAccessor();


            context.Services.AddHealthChecks();

            context.Services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true);
            context.Services.AddScoped<SlidingExpirationMiddleware>();
            return base.ConfigureServicesAsync(context);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            //读取请求体设置可以重复读取
            app.Use((httpContext, next) =>
            {
                httpContext.Request.EnableBuffering();
                httpContext.Response.Headers.Append("Access-Control-Allow-Private-Network", "true");
                return next(httpContext);
            });
            app.UseAuthorization();
            app.UseAuthentication();
             app.UseMiddleware<SlidingExpirationMiddleware>();
            //静态文件
            app.UseDefaultFiles();
            app.UseStaticFiles();
            app.UseCors("AllowCors");

            // Configure the HTTP request pipeline.
            // if (app.Environment.IsDevelopment())
            // {
            app.UseCoreSwagger();
            // }


            app.UseHttpsRedirection();

            app.UseHeaderPropagation();
            app.UseRouting();
            app.UseConfiguredEndpoints();

            return base.OnApplicationInitializationAsync(context);
        }
    }
}